﻿using Prism.Mvvm;
using System;
using System.Collections.ObjectModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading;
using System.Windows;

namespace IntoLog
{
    public class LogService : BindableBase
    {
        /// <summary>
        /// 日志缓存
        /// </summary>
        private LogQueue buffer = new LogQueue();
        /// <summary>
        /// 延时处理，以减少数据库资源
        /// </summary>
        private Timer delayTimer;
        /// <summary>
        /// 锁
        /// </summary>
        private object locker = new object();

        public LogService()
        {
            Init();
        }

        /// <summary>
        /// 界面显示的日志，容量1000
        /// </summary>
        public ObservableCollection<LogMsg> Logs { get; set; } = new ObservableCollection<LogMsg>();
        /// <summary>
        /// 延时记录数据
        /// </summary>
        private void Tick()
        {
            if (delayTimer == null)
            {
                delayTimer = new Timer(delegate
                {
                    Save();
                }, null, 1000, 0);
            }
            else if (buffer.Count >= 1000)
            {
                delayTimer.Change(0, 0);
            }
            else
            {
                delayTimer.Change(1000, 0);
            }
        }

        /// <summary>
        /// 保留一个月的操作日志
        /// </summary>
        private void Init()
        {
            try
            {


                lock (locker)
                {
                    using (LogDbContext db = new LogDbContext())
                    {
                        DateTime oneMonthAgo = DateTime.Now.AddDays(-30);
                        var list = db.Logs.Where(o => o.LogTime <= oneMonthAgo.Date).ToList();
                        if (list != null && list.Count > 0)
                        {
                            db.Logs.RemoveRange(list);
                            db.SaveChanges();
                        }
                    }
                }
            }
            catch (Exception ex)
            {


            }
        }
        /// <summary>
        /// 保存日志
        /// </summary>
        private void Save()
        {
            try
            {


                lock (locker)
                {
                    if (buffer.Count <= 0) return;
                    using (LogDbContext db = new LogDbContext())
                    {
                        var list = buffer.DequeueAll();
                        foreach (var item in list)
                        {
                            LogMsg msg = item as LogMsg;
                            db.Logs.Add(msg);
                        }
                        db.SaveChanges();
                    }
                }
            }
            catch (Exception)
            {

               
            }
        }

        /// <summary>
        /// 添加到界面显示链表
        /// </summary>
        private void AddLog(LogMsg msg)
        {
            Application.Current.Dispatcher.Invoke(() =>
            {
                if (Logs.Count > 1000)
                {
                    Logs.RemoveAt(0);
                }
                Logs.Add(msg);
            });
        }

        /// <summary>
        /// 记录提示信息
        /// </summary>
        public void LogTip(string msg, string station)
        {
            lock (locker)
            {
                LogMsg log = new LogMsg();
                log.Msg = msg;
                log.LogTime = DateTime.Now;
                log.MsgType = MsgType.Tip;
                log.Station = station;
                buffer.Enqueue(log);
                AddLog(log);
                Tick();
            }
        }
        /// <summary>
        /// 记录警告信息
        /// </summary>
        public void LogWarning(string msg, string station)
        {
            lock (locker)
            {
                LogMsg log = new LogMsg();
                log.Msg = msg;
                log.LogTime = DateTime.Now;
                log.MsgType = MsgType.Warning;
                log.Station = station;
                buffer.Enqueue(log);
                AddLog(log);
                Tick();
            }
        }
        /// <summary>
        /// 记录报警信息
        /// </summary>
        public void LogAlarm(string msg, string station)
        {
            lock (locker)
            {
                LogMsg log = new LogMsg();
                log.Msg = msg;
                log.LogTime = DateTime.Now;
                log.MsgType = MsgType.Error;
                log.Station = station;
                buffer.Enqueue(log);
                AddLog(log);
                Tick();
            }
        }
    }

    public class LogMsg
    {
        [Key]
        public int Count { get; set; }
        /// <summary>
        /// 记录时间
        /// </summary>
        public DateTime LogTime { get; set; }
        /// <summary>
        /// 消息类型
        /// </summary>
        public MsgType MsgType { get; set; }
        /// <summary>
        /// 消息内容
        /// </summary>
        public string Msg { get; set; }
        /// <summary>
        /// 工位号
        /// </summary>
        public string Station { get; set; }

    }

    /// <summary>
    /// 消息类型
    /// </summary>
    public enum MsgType
    {
        Tip = 1,
        Warning = 2,
        Error = 3,
    }
}
